

import java.io.* ;
import java.net.* ;
import java.util.HashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * <p>Title: </p>
 * <p>Description: Processor super class </p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: ShenYang newtribe.external Corp .</p>
 * @author fuwei ,fuw@newtribe.external.com
 * @version 1.0
 */

public abstract class Processor implements Runnable {

  public Processor(Server parent ,int seq) {
     this.parent =parent ;
     this.sequence =seq ;
   }

   /**
    * Give the sub server concrete class a change to initialize .
    */
   protected abstract  void init()  ;

   /**
    * the sub Server Processor class must override .
    * when accept , process a socket .
    * @throws java.lang.Exception
    */
   
   abstract void process(Socket socket ) throws Exception ;


   public final void run() {
     threadDoStart();
   }

   private void threadDoStart() {
    // System.out.println (Thread.currentThread().getName() +"start ...") ;
      while (!stop) {
         ready() ;
         if(this.socket !=null) {
           try {

             process(socket) ;
             if(socket !=null)
               socket.close() ;
           }
           catch(Throwable e) {
             e.printStackTrace();
           }finally {
           parent.recycle(this) ;
           this.socket =null ;
           }
         }
      }
      log.info(Thread.currentThread() .getName()  +"processor stopped !") ;
   }

   private synchronized void ready() {
      while (stop ==false &&socket ==null) {
        log.info(Thread.currentThread() .getName() +" wait connection ..." ) ;
          try {
            wait() ;
          }catch(Exception e) {

          }
      }
   }

   public void start() {
     init() ;
     Thread thread =new Thread(this,parent.getServiceName()+"processor"+sequence) ;
     thread.start();
   }
   public void stop () {
     stop =true ;
   }
   public synchronized void assign(Socket socket ) {
     this.socket =socket ;
     notifyAll() ;
   }
   public boolean available() {
     return this.socket ==null ;
   }

   public static Log log =LogFactory.getLog(Processor.class) ;
   //========================================variables
   private boolean stop =false ;

   protected Server parent = null ;
   protected Socket socket =null ;
   
   protected int sequence ;

   public static void main(String[] args) {
   }
}